package com.cisdi.info.simple.util;

import com.cisdi.info.simple.DDDException;
import com.cisdi.info.simple.dao.permission.RoleAndPermissionDao;
import com.cisdi.info.simple.entity.permission.Module;
import com.cisdi.info.simple.entity.permission.Permission;
import com.cisdi.info.simple.entity.permission.RoleAndPermission;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class ModuleManager {
    private static Logger logger = LogManager.getLogger();
    private static Map<String,Module> modules ;
    private static Map<String,Set<Long>> urlRoles =  new HashMap<String, Set<Long>>();

    public static  Module findModule(String code)
    {
        return getModules().get(code);
    }
    public static void loadModules()
    {
        loadModules(Config.moduleFile);
    }

    public static void initialize()
    {
        RoleAndPermissionDao roleAndPermissionDao = (RoleAndPermissionDao)SpringContextUtils.getBean("roleAndPermissionDao");

        List<RoleAndPermission> roleAndPermissions = roleAndPermissionDao.findAllRoleAndPermissions();
        Map<String,List<String>> permissionMap = new HashMap<String, List<String>>();

        for(Module module:getModules().values())
        {
            for(Permission permission:module.getPermissions()) {
                permissionMap.put(permission.getCode(),permission.getUrls());
            }
        }


        for(RoleAndPermission roleAndPermission : roleAndPermissions)
        {
            List<String> urls = permissionMap.get(roleAndPermission.getPermissionCode());
            if(urls == null) continue;
            for (String url : urls)
            {
                Set<Long> roles = urlRoles.get(url);
                if(roles == null)
                {
                    roles = new HashSet<Long>();
                    urlRoles.put(url, roles);
                }
                roles.add(roleAndPermission.getRoleId());
            }
        }
    }
    public static boolean hasPermission(String url,List<Long> roleIds)
    {
        for(Long roleId : roleIds)
        {
            if(hasPermission(url,roleId))
            {
                return  true;
            }
        }

        return false;
    }
    public static boolean hasPermission(String url,Long roleId)
    {
        Set<Long> roles = urlRoles.get(url);
        if(roles == null)
        {
            logger.error(String.format("非法请求 %s,可能是恶意攻击，请报告管理员",url));
            return false;
        }
        if(roles.contains(roleId))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public static void loadModules(String file)
    {
        if(modules != null) return ;

        Gson gson = new Gson();
        String json = null;
        try {
            json = FileUtils.readFileToString(new File(file), "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        modules = gson.fromJson(json, new TypeToken<Map<String,Module>>() {}.getType());
    }
    private static  Map<String,Module> getModules()
    {
        loadModules();
        return modules;
    }
    public static  void addModule(String code, Module newModule)
    {

        getModules().put(code, newModule);

        saveModules(Config.moduleFile);
    }

    public static void  addModuleFromJson(String moduleJson)
    {
        Gson gson = new Gson();
        Map<String,Module> newModules = gson.fromJson(moduleJson, new TypeToken<Map<String,Module>>() {}.getType());

        for(Module module : newModules.values())
        {
            addModule(module);
        }
        saveModules(Config.moduleFile);
    }
    public static void  addModule(Module module)
    {
        String code = StringUtils.trimToEmpty(module.getCode());
        String[] codeParts = StringUtils.split(code, '/');
        if(codeParts.length != 3)
        {
            throw new DDDException("%s 是无效的模块编码，格式如：system_module_entity");
        }

        String systemCode =codeParts[0];
        Module systemModule = findModuleByCode(systemCode);
        if(systemModule == null)
        {
            systemModule = new Module(systemCode,systemCode,"","","",1l,"是",module.getModuleType(),"");
            addModule(systemCode, systemModule);
        }

        String moduleCode =systemCode+"/"+codeParts[1];
        Module moduleModule = findModuleByCode(moduleCode);
        if(moduleModule == null)
        {
            moduleModule = new Module(moduleCode,module.getParentName(),"","","",1l,module.getModuleType(),"是","",systemModule);
            addModule(moduleCode, moduleModule);
        }
        addModule(code, module);
        saveModules(Config.moduleFile);
    }

//    public static void  addModule(String code, String name, String url, String route, String iconClass, Long displayIndex, String moduleType,  String routeParamsObj,String moduleName)
//    {
//        code = StringUtils.trimToEmpty(code);
//        String[] codeParts = StringUtils.split(code, '/');
//        if(codeParts.length != 3)
//        {
//            throw new DDDException("%s 是无效的模块编码，格式如：system_module_entity");
//        }
//
//        String systemCode =codeParts[0];
//        Module systemModule = findModuleByCode(systemCode);
//        if(systemModule == null)
//        {
//            systemModule = new Module(systemCode,systemCode,"","","",1l,"是",moduleType,"");
//            addModule(systemCode, systemModule);
//        }
//
//        String moduleCode =systemCode+"/"+codeParts[1];
//        Module moduleModule = findModuleByCode(moduleCode);
//        if(moduleModule == null)
//        {
//            moduleModule = new Module(moduleCode,moduleName,"","","",1l,moduleType,"是","",systemModule);
//            addModule(moduleCode, moduleModule);
//        }
//
//        String entityCode =moduleCode+"/"+codeParts[2];
//        Module entityModule = findModuleByCode(entityCode);
//        if(entityModule == null)
//        {
//            entityModule = new Module(entityCode,name,url,route,iconClass,displayIndex,moduleType,"是",routeParamsObj,moduleModule);
//            addModule(entityCode, entityModule);

//            String fulleName = null;
//            String baseUrl = "";
//            List<String> urls = null;
//DDDErrorController
//            fulleName = StringUtils.join(new String[]{systemModule.getName(),moduleModule.getName(),entityModule.getName(),"新增"},".");
//            urls = new ArrayList<String>();
//            urls.add("");
//
////            entityModule.getPermissions().add(new Permission(entityCode+"/Add","新增",fulleName,entityCode));
////
////            fulleName = StringUtils.join(new String[]{systemModule.getName(),moduleModule.getName(),entityModule.getName(),"编辑"},".");
////            entityModule.getPermissions().add(new Permission(entityCode+"/Edit","编辑",fulleName,entityCode));
////
////            fulleName = StringUtils.join(new String[]{systemModule.getName(),moduleModule.getName(),entityModule.getName(),"删除"},".");
////            entityModule.getPermissions().add(new Permission(entityCode+"/Delete","删除",fulleName,entityCode));
////
////            fulleName = StringUtils.join(new String[]{systemModule.getName(),moduleModule.getName(),entityModule.getName(),"查看"},".");
////            entityModule.getPermissions().add(new Permission(entityCode+"/View","查看",fulleName,entityCode));
//        }
//
//        saveModules(Config.moduleFile);
//    }
    public static  Module findModuleByCode(String code)
    {
        return getModules().get(code);
    }

    public static  void removeModule(String code)
    {
        getModules().remove(code);

        saveModules(Config.moduleFile);
    }
    public static void saveModules(String file)
    {
        Gson gson = createGson();
        String json = gson.toJson(getModules());
        try {
            FileUtils.writeStringToFile(new File(file), json, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static  Collection<Module> getAllModules()
    {
        return getModules().values();
    }
    private static Gson createGson()
    {
        return new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .enableComplexMapKeySerialization() //当Map的key为复杂对象时,需要开启该方法
                .serializeNulls() //当字段值为空或null时，依然对该字段进行转换
                .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS") //时间转化为特定格式
                .setPrettyPrinting() //对结果进行格式化，增加换行
                .disableHtmlEscaping().create(); //防止特殊字符出现乱码
    }
    public static  void main(String[] args)
    {
        modules = new HashMap<String, Module>();

        Module simpleModule = new Module("simple", "系统管理", "", "", "", 1l, "电脑模块", "是", "");
        modules.put(simpleModule.getCode(), simpleModule);

        saveModules("F:\\IDEA\\workspace\\xc-project\\src\\main\\resources\\modules.json");
        loadModules("F:\\IDEA\\workspace\\xc-project\\src\\main\\resources\\modules.json");

        System.out.println(modules.toString());
    }
}
